package com.idanchuang.component.sentinel.runner;

import com.alibaba.csp.sentinel.init.InitExecutor;
import com.idanchuang.component.sentinel.config.SentinelConfigBean;
import com.zoi7.component.core.base.BaseClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

/**
 *
 * 初始化sentinel相关配置
 *
 * @author yjy
 * @date 2020/1/9 9:34
 **/
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SentinelConfigRunner extends BaseClass implements CommandLineRunner {

    private static final Logger log = LoggerFactory.getLogger(SentinelConfigRunner.class);

    /** 配置是否加载完成 */
    public static boolean configLoaded = false;

    @Autowired
    private SentinelConfigBean sentinelConfigBean;

    @Override
    public void run(String... args) throws Exception {
        // 指定应用的名称
        putSystemProperty("project.name", sentinelConfigBean.getProjectName());
        // 指定应用的类型 {@link APP_TYPE_COMMON}
        putSystemProperty("csp.sentinel.app.type", sentinelConfigBean.getAppType());
        // 单个监控日志文件的大小
        putSystemProperty("csp.sentinel.metric.file.single.size", sentinelConfigBean.getMetricFileSingleSize());
        // 监控日志文件的总数上限
        putSystemProperty("csp.sentinel.metric.file.total.count", sentinelConfigBean.getMetricFileTotalCount());
        // 最大的有效响应时长（ms），超出此值则按照此值记录
        putSystemProperty("csp.sentinel.statistic.max.rt", sentinelConfigBean.getStatisticMaxRt());
        // SPI 加载时使用的 ClassLoader，默认为给定类的 ClassLoader
        putSystemProperty("csp.sentinel.spi.classloader", sentinelConfigBean.getSpiClassloader());
        // Sentinel 日志文件目录
        putSystemProperty("csp.sentinel.log.dir", sentinelConfigBean.getLogDir());
        // 日志文件名中是否加入进程号，用于单机部署多个应用的情况
        putSystemProperty("csp.sentinel.log.use.pid", sentinelConfigBean.isLogUsePid());
        // Record 日志输出的类型，file 代表输出至文件，console 代表输出至终端
        putSystemProperty("csp.sentinel.log.output.type", sentinelConfigBean.getLogOutputType());
        // 控制台的地址，指定控制台后客户端会自动向该地址发送心跳包。地址格式为：hostIp:port
        putSystemProperty("csp.sentinel.dashboard.server", sentinelConfigBean.getDashboardServer());
        // 心跳包发送周期，单位毫秒
        putSystemProperty("csp.sentinel.heartbeat.interval.ms", sentinelConfigBean.getHeartbeatIntervalMs());
        // 本地启动 HTTP API Server 的端口号
        putSystemProperty("csp.sentinel.api.port", sentinelConfigBean.getApiPort());
        // 指定心跳包中本机的 IP
        putSystemProperty("csp.sentinel.heartbeat.client.ip", sentinelConfigBean.getHeartbeatClientIp());

        if (!sentinelConfigBean.isLazyInit()) {
            // If init fails, the process will exit.
            InitExecutor.doInit();
        }
        configLoaded = true;
    }

    private void putSystemProperty(String key, Object value) {
        String v = value != null ? value.toString() : "";
        System.setProperty(key, v);
        log.info("Set Sentinel System property > key: {}, value: {}", key, v);
    }

}
